#include "resource.h"
#include "misc.h"
#include <cstring>

namespace helper {

ResourceManager::ResourceManager() :
    image_list(),
    music_list(),
    chunk_list(),
    text_list()
{
}

ResourceManager::~ResourceManager()
{
    free_all();
}

void ResourceManager::free_all()
{
    Node<SDL_Surface *> *node_image = NULL;
    while (!image_list.empty()) {
        node_image = image_list.get_front();
        SDL_FreeSurface(image_list.get_front()->value);
        image_list.pop_front();
        delete node_image;
    }
    Node<Mix_Music *> *node_music = NULL;
    while (!music_list.empty()) {
        node_music = music_list.get_front();
        Mix_FreeMusic(music_list.get_front()->value);
        music_list.pop_front();
        delete node_music;
    }
    Node<Mix_Chunk *> *node_chunk = NULL;
    while (!chunk_list.empty()) {
        node_chunk = chunk_list.get_front();
        Mix_FreeChunk(chunk_list.get_front()->value);
        chunk_list.pop_front();
        delete node_chunk;
    }
    Node<char *> *node_text = NULL;
    while (!text_list.empty()) {
        node_text = text_list.get_front();
        free(node_text->value);
        text_list.pop_front();
        delete node_text;
    }
}

SDL_Surface *ResourceManager::get_image(const char *name)
{
    Node<SDL_Surface *> *node = NULL;
    image_list.iterator_reset();
    for (int i=0; i<image_list.size(); i++) {
        node = image_list.iterator_get_next();
        if (strncmp(node->name, name, sizeof(node->name)) == 0) {
            return node->value;
        }
    }
    throw "Resource not found";
}

Mix_Music *ResourceManager::get_music(const char *name)
{
    Node<Mix_Music *> *node = NULL;
    music_list.iterator_reset();
    for (int i=0; i<music_list.size(); i++) {
        node = music_list.iterator_get_next();
        if (strncmp(node->name, name, sizeof(node->name)) == 0) {
            return node->value;
        }
    }
    throw "Resource not found";
}

Mix_Chunk *ResourceManager::get_chunk(const char *name)
{
    Node<Mix_Chunk *> *node = NULL;
    chunk_list.iterator_reset();
    for (int i=0; i<chunk_list.size(); i++) {
        node = chunk_list.iterator_get_next();
        if (strncmp(node->name, name, sizeof(node->name)) == 0) {
            return node->value;
        }
    }
    throw "Resource not found";
}

const char *ResourceManager::get_text(const char *name)
{
    Node<char *> *node = NULL;
    text_list.iterator_reset();
    for (int i=0; i<text_list.size(); i++) {
        node = text_list.iterator_get_next();
        if (strncmp(node->name, name, sizeof(node->name)) == 0) {
            return node->value;
        }
    }
    throw "Resource not found";
}

SDL_Surface *ResourceManager::load_image(const char *path)
{
    SDL_Surface *loaded = NULL;
    const char *name = NULL;

    if (path == NULL) {
        return NULL;
    }
    name = strrchr(path, '/');
    if (name == NULL) {
        name = path;
    } else {
        name = name + 1;
    }
    loaded = IMG_Load(path);
    if (loaded == NULL) {
        throw IMG_GetError();
    }
    Node<SDL_Surface *> *node = new Node<SDL_Surface *>(name);
    node->value = loaded;
    image_list.push_front(node);
    return loaded;
}

Mix_Music *ResourceManager::load_music(const char *path)
{
    Mix_Music *loaded = NULL;
    const char *name = NULL;

    if (path == NULL) {
        return NULL;
    }
    name = strrchr(path, '/');
    if (name == NULL) {
        name = path;
    } else {
        name = name + 1;
    }
    loaded = Mix_LoadMUS(path);
    if (loaded == NULL) {
        throw Mix_GetError();
    }
    Node<Mix_Music *> *node = new Node<Mix_Music *>(name);
    node->value = loaded;
    music_list.push_front(node);
    return loaded;
}

void ResourceManager::load_textcollection(const char *path)
{
    if (path == NULL) {
        throw "NULL path";
    }

    FILE *fptr = fopen(path, "r");
    if (fptr == NULL) {
        throw "Can't open file";
    }
    while (!feof(fptr)) {
        char buffer[1024];
        char *name = NULL;
        size_t namelen = 0;
        char *value = NULL;
        size_t valuelen = 0;

        fgets(buffer, sizeof(buffer), fptr);
        name = buffer;
        value = strchr(buffer, '=');
        if (value == NULL) {
            throw "file parse error";
        } else {
            value = value + 1;
        }
        namelen = value - name - 1;
        valuelen = strlen(buffer) - namelen - 1;
        name [namelen] = '\0';

        //remove all \r or \n at the end of the string
        char *tmpptr = value + valuelen - 1;
        while (tmpptr > value) {
            if (*tmpptr == '\r' || *tmpptr == '\n') {
                *tmpptr = '\0';
            }
            tmpptr--;
        }

        Node<char *> *node = new Node<char *>(name);
        node->value = strdup(value);
        text_list.push_back(node);
        //printf("name:%s, namelen:%d\nvalue:%s, valuelen:%d\n", node->name, namelen, node->value, valuelen);
    }
    fclose(fptr);
    return;
}


}
